﻿Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Class transfer

    Private filename As String
    Property complete As Boolean = False
    Private connNumber As Integer
    Property waiting As Boolean
    Property uID As Integer
    Private clients As SortedDictionary(Of Integer, TcpClient) = New SortedDictionary(Of Integer, TcpClient)

    Sub New(ByVal filename As String, ByVal numberConn As Integer, ByVal uID As Integer)
        Me.filename = filename
        connNumber = numberConn
        Me.uID = uID
        waiting = False
    End Sub

    Sub add(ByVal client As TcpClient, ByVal order As Integer)
        clients.Add(order, client)
        If (connNumber = clients.Count) Then
            waiting = True
        End If
    End Sub

    Sub beginTransfer()
        waiting = False
        Dim t As Thread = New Thread(AddressOf transferTask)
        t.Start()
    End Sub

    Sub transferTask()
        'Dim tmpsize As Integer = filename.Length()
        Dim f As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim finished As Boolean = False
        Dim last As Integer
        Dim totalSize, partSize As Long
        Dim threads As ArrayList = New ArrayList
        last = 0
        totalSize = f.Length
        f.Dispose()
        partSize = Math.Floor(totalSize / connNumber)
        For Each c As KeyValuePair(Of Integer, TcpClient) In clients
            Dim st As New Thread(AddressOf subTransTask)
            st.Start(New transpart(partSize, filename, c.Value, last))
            threads.Add(st)
            last += 1
        Next
        While (Not finished)
            Dim tmp As Integer = 0
            For Each thre As Thread In threads
                If (Not thre.IsAlive) Then
                    tmp += 1
                End If
            Next
            If (tmp = threads.Count) Then
                finished = True
            End If
        End While
        complete = True
    End Sub

    Private Sub subTransTask(ByVal tr As transpart)
        Dim reader As New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)
        'Dim reader As New BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
        Dim writer As New NetworkStream(tr.c.Client)
        Dim read As Integer
        Dim b(25000000) As Byte
        Dim offset As Long = tr.s * tr.n
        Dim left As Long = tr.s
        'If (offset + tr.s >= reader.Length) Then
        '    read = reader.Read(b, offset, (reader.Length - offset))
        'Else
        'read = reader.Read(b, offset, tr.s)
        reader.Position = offset
        While (left > 0)
            read = reader.Read(b, 0, 25000000)
            writer.Write(b, 0, read)
            writer.Flush()
            left = left - read
        End While
        'read = reader.Read(b, 0, tr.s)
        'End If
        reader.Close()
        writer.Close()
        tr.c.Close()
    End Sub

    Private Class transpart
        Property f As String
        Property s As Long
        Property c As TcpClient
        Property n As Long

        Public Sub New(ByVal size As Long, ByVal files As String, ByVal client As TcpClient, ByVal num As Long)
            f = files
            s = size
            c = client
            n = num
        End Sub
    End Class

End Class
